﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Windows.Forms;

namespace docExplorer
{
    public class AddinUtils
    {
        /// <summary>
        /// Open Choose Document
        /// </summary>
        /// <param name="filePath">Path of the file to open</param>
        public static void OpenDocument(object filePath)
        {
            try
            {
                object miss = Globals.ThisAddIn._missing;
                object fake = false;
                Globals.ThisAddIn.Application.Documents.Open(ref filePath, ref fake, ref fake, ref miss, ref miss,
                                                            ref miss, ref miss, ref miss, ref miss, ref miss, ref miss,
                                                            ref miss, ref miss, ref miss, ref miss, ref miss);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex.InnerException);
            }

            if (Globals.ThisAddIn.ExplorerCTP != null)
                if (!Globals.ThisAddIn.ExplorerCTP.Visible)
                    Globals.Ribbons.rbbDocExplorer.btnExplorer.Checked = Globals.ThisAddIn.ExplorerCTP.Visible;
        }

        /// <summary>
        /// Sort node and child nodes
        /// </summary>
        /// <param name="sortNode">node to sort</param>
        /// <returns>node sorted</returns>
        public static TreeNode TreeViewSort(TreeNode sortNode)
        {
            List<TreeNode> lstNodesCategory = new List<TreeNode>();
            List<TreeNode> lstNodesDoc = new List<TreeNode>();
            foreach (TreeNode node in sortNode.Nodes)
            {
                if (((TreeNodeContents)node.Tag).Type == TreeNodeType.Category)
                    lstNodesCategory.Add(AddinUtils.TreeViewSort(node));
                else
                    lstNodesDoc.Add(node);
            }
            TreeNode[] nodesCategory = AddinUtils.ShellSortTreeNodes(lstNodesCategory.ToArray());
            TreeNode[] nodesDoc = AddinUtils.ShellSortTreeNodes(lstNodesDoc.ToArray());
            sortNode.Nodes.Clear();
            sortNode.Nodes.AddRange(nodesCategory);
            sortNode.Nodes.AddRange(nodesDoc);
            return sortNode;
        }

        /// <summary>
        /// Sort only this node
        /// </summary>
        /// <param name="sortNode">node to sort</param>
        /// <returns>node sorted</returns>
        public static TreeNode TreeNodeSort(TreeNode sortNode)
        {
            List<TreeNode> lstNodesCategory = new List<TreeNode>();
            List<TreeNode> lstNodesDoc = new List<TreeNode>();
            foreach (TreeNode node in sortNode.Nodes)
            {
                if (((TreeNodeContents)node.Tag).Type == TreeNodeType.Category)
                    lstNodesCategory.Add(node);
                else
                    lstNodesDoc.Add(node);
            }
            TreeNode[] nodesCategory = AddinUtils.ShellSortTreeNodes(lstNodesCategory.ToArray());
            TreeNode[] nodesDoc = AddinUtils.ShellSortTreeNodes(lstNodesDoc.ToArray());
            sortNode.Nodes.Clear();
            sortNode.Nodes.AddRange(nodesCategory);
            sortNode.Nodes.AddRange(nodesDoc);
            return sortNode;
        }

        public static TreeNode[] ShellSortTreeNodes(TreeNode[] treeNodes)
        {
            int i, j, increment, count = treeNodes.Count();
            TreeNode temp;
            increment = 3;

            while (increment > 0)
            {
                for (i = 0; i < count; i++)
                {
                    j = i;
                    temp = treeNodes[i];

                    while ((j >= increment) && (Convert.ToBoolean(treeNodes[j - increment].Text.CompareTo(temp.Text))))
                    {
                        treeNodes[j] = treeNodes[j - increment];
                        j = j - increment;
                    }

                    treeNodes[j] = temp;
                }

                if (increment / 2 != 0)
                {
                    increment = increment / 2;
                }
                else if (increment == 1)
                {
                    increment = 0;
                }
                else
                {
                    increment = 1;
                }
            }
            return treeNodes;
        }

        public static TreeNodeType TypeByString(string type)
        {
            if (type == "Category")
                return TreeNodeType.Category;
            else if (type == "Doc")
                return TreeNodeType.Doc;
            else if (type == "Root")
                return TreeNodeType.Root;
            return new TreeNodeType();
        }

    }

    public class TreeNodeContents
    {
        #region Properties

        private string path = string.Empty;
        public string Path
        {
            get { return path; }
            set { path = value; }
        }

        private string template = string.Empty;
        public string Template
        {
            get { return template; }
            set { template = value; }
        }

        private string create = string.Empty;
        public string Create
        {
            get { return create; }
            set { create = value; }
        }

        private TreeNodeType type;
        public TreeNodeType Type
        {
            get { return type; }
            set { type = value; }
        }

        #endregion

        public TreeNodeContents()
        {
            this.Type = TreeNodeType.Root;
        }

        public TreeNodeContents(string Path)
        {
            this.Path = Path;
            this.Type = TreeNodeType.Doc;
        }

        public TreeNodeContents(string Path, TreeNodeType Type)
        {
            this.Path = Path;
            this.Type = Type;
        }

        public TreeNodeContents(string Path, string Template, string Create)
        {
            this.Path = Path;
            this.Template = Template;
            this.Create = Create;
            this.Type = TreeNodeType.Category;
        }

        public TreeNodeContents(string Path, string Template, string Create, TreeNodeType Type)
        {
            this.Path = Path;
            this.Template = Template;
            this.Create = Create;
            this.Type = Type;
        }
    }

    public enum TreeNodeType
    { 
        Root,
        Category,
        Doc
    }
}
